﻿using System.Collections.Generic;
using System.Linq;
using Inkubator.Wizard.WebWizard.WizardControl;
using Inkubator.Wizard.Model.ConditionalMode;
using System.Web.UI.WebControls;

namespace Inkubator.Wizard.WebWizard.WizardUtilities
{
    /// <summary>
    /// This class evaluate the conditional cases where the Wizard can
    /// take different paths to be completed.
    /// </summary>
    public class ConditionalProgress
    {
        /// <summary>
        /// The Wizard Control.
        /// </summary>
        private WizardWeb wizard;
        /// <summary>
        /// The current step.
        /// </summary>
        private int active;

        /// <summary>
        /// This method analyze the different conditions from the current step.
        /// </summary>
        /// <param name="active"></param>
        /// <param name="progress"></param>
        /// <param name="wizard"></param>
        /// <returns></returns>
        public int analyzeConditions(int active, StepProgress progress, WizardWeb wizard)
        {
            if (progress != null)
            {
                this.active = active;
                this.wizard = wizard;

                StepWizard step = wizard.getSteps().ElementAt(active);
                for (int i = 0; i < progress.conditions.Count; i++)
                {
                    if (step.ID.Equals(progress.conditions.ElementAt(i).actual))
                    {
                        string stepTarget = this.evaluateAlternatives(progress.conditions.ElementAt(i).alternatives);

                        if (stepTarget.Equals(""))
                        {
                            break;
                        }

                        for (int j = 0; j < wizard.getSteps().Count; j++)
                        {
                            if (stepTarget.Equals(wizard.getSteps().ElementAt(j).ID))
                            {
                                return j;
                            }
                        }
                    }

                }
            }

            return ++active;
        }

        /// <summary>
        /// This method analyze the different alternatives for each condition.
        /// </summary>
        /// <param name="alternatives"></param>
        /// <returns></returns>
        private string evaluateAlternatives(Alternatives alternatives)
        {
            for (int i = 0; i < alternatives.options.Count; i++)
            {
                string result = this.evaluateOption(alternatives.options.ElementAt(i));
                if (!result.Equals(""))
                {
                    return result;
                }
            }

            return "";
        }

        /// <summary>
        /// This method analyze each option contained in the alternative selected.
        /// </summary>
        /// <param name="option"></param>
        /// <returns></returns>
        private string evaluateOption(Option option)
        {
            if (option.evaluate != null)
            {
                ActionWizard action = new ActionWizard(option.evaluate.assemblyName, option.evaluate.method,
                    option.evaluate.impInterface);

                StepWizard step = wizard.getSteps().ElementAt(active);

                List<WebControl> controls = step.obtainAllControls();

                if (action.evaluate(controls.ToArray()))
                {
                    return option.target;
                }
            }
            else
            {
                CompileExpression compile = new CompileExpression(option.selectionMode, this.wizard, this.active);

                if (compile.compile())
                {
                    return option.target;
                }
            }

            return "";
        }

    }
}
